package puzzle.sudoku.data;

import puzzle.common.point.Pnt;

public abstract class NumGroupSelector {
	public enum NumGroupType {
		VERTICAL, HORIZONTAL, RECTANGLE
	};

	public final int base;

	public NumGroupSelector(int base) {
		this.base = base;
	}

	public abstract int select(int x, int y);

	public abstract Pnt[] createPoints(int i);

	public static NumGroupSelector createVertical(int base) {
		return new NumGroupSelector(base) {
			@Override
			public int select(int x, int y) {
				return x;
			}

			@Override
			public Pnt[] createPoints(int i) {
				Pnt[] result = new Pnt[base * base];
				for (int y = 0; y < result.length; y++) {
					result[y] = new Pnt(i, y);
				}
				return result;
			}
		};
	}

	public static NumGroupSelector createHorizontal(int base) {
		return new NumGroupSelector(base) {
			@Override
			public int select(int x, int y) {
				return y;
			}

			@Override
			public Pnt[] createPoints(int i) {
				Pnt[] result = new Pnt[base * base];
				for (int x = 0; x < result.length; x++) {
					result[x] = new Pnt(x, i);
				}
				return result;
			}
		};
	}

	public static NumGroupSelector createRectangle(int base) {
		return new NumGroupSelector(base) {
			@Override
			public int select(int x, int y) {
				return (x / base) + (y / base) * base;
			}

			@Override
			public Pnt[] createPoints(int i) {
				Pnt[] result = new Pnt[base * base];
				int x0 = (i % base) * base;
				int y0 = (i / base) * base;
				for (int y = 0; y < base; y++) {
					for (int x = 0; x < base; x++) {
						result[x + y * base] = new Pnt(x0 + x, y0 + y);
					}
				}
				return result;
			}
		};
	}

	public static NumGroupSelector[] createStandardSelectors(int base) {
		return new NumGroupSelector[] { createVertical(base), createHorizontal(base),
				createRectangle(base) };
	}

}
